﻿using System.Collections.Generic;
using System.Web;
using Sissonix.ExtRest.Exception;
using Sissonix.Infrastructure.RepositoryFramework;
using mgrModel = Sissonix.ExtRest.RestManagerModel.Model;
using mgrRepo = Sissonix.ExtRest.RestManagerModel.Repository;
using schemaModel = Sissonix.ExtRest.RestSchemaModel.Model;
using schemaRepo = Sissonix.ExtRest.RestSchemaModel.Repository;
using Sissonix.ExtRest.WADL;

namespace Sissonix.ExtRest.RestManager.Processors
{
    class ManagedAppProcessor : BaseRestProcessor
    {
        mgrRepo.IManagedAppRepository repo;

        public ManagedAppProcessor() {
            try
            {
                repo = RepositoryFactory.GetRepository<mgrRepo.IManagedAppRepository, mgrModel.ManagedApp>();
            }
            catch (System.Exception e)
            {
                throw new RestException("ApplicationProcessor could not find a repository defined for Application.", e);
            }
        }

        public new void ProcessRequest(WADLContext context)
        {
            base.ProcessRequest(context);
        }

        public override void ProcessDelete(WADLContext context)
        {
            //HttpRequest req = HttpContext.Current.Request;
            //int? id = context.DomainId;
            //int x;
            //if (id == 0 && int.TryParse(req.Form["ApplicationID"],out x))
            //{
            //    id = int.Parse(req.Form["ApplicationID"]);
            //}
            //else
            //{
            //    string ids = req.Form["ids"];
            //    string frm = req.Form.ToString();
            //    frm = HttpUtility.HtmlDecode(frm);

            //    mgrRepo.IManagedAppRepository repo = RepositoryFactory.GetRepository<mgrRepo.IManagedAppRepository, mgrModel.ManagedApp>();
            //    repo.Remove(long.Parse(ids));
            //}
        }


        public void ProcessTreeRequest(WADLContext context)
        {            
            HttpContext ctx = HttpContext.Current;

            string node = ctx.Request.Params["node"];
            string appNodeCls = ctx.Request.Params["appNodeCls"];
            string domainNodeCls = ctx.Request.Params["domainNodeCls"];

            if (node+"" == "") node = "main";

            string[] nodeParts = node.Split('-');
            string managedAppID = nodeParts[0];
            string rslt = ""; 

            //****** PROCESSING THE ROOT APPLICATION NODE *****//
            if (node == "main")
            {
                IList<mgrModel.ManagedApp> records = repo.FindAll(0, int.MaxValue, "AppName", "ASC");

                foreach (mgrModel.ManagedApp a in records)
                {
                    if (rslt != "")
                        rslt += ",";

                    //1. Make each application a non-leaf so that it gets expanded. 
                    //2. Set the cls to the cls sent from the browser
                    rslt += string.Format(@"{{""id"":""{0}"",""leaf"":false,""text"":""{1}"",""cls"":""{2}""}}",
                        a.ManagedAppID.ToString(), a.AppName, appNodeCls);
                }
            }
            else
            {
                //****** PROCESSING A NODE WITHIN AN APPLICATION *****//
                mgrModel.ManagedApp mgrApp = repo.FindBy(managedAppID);

                //TODO - Check if we should factory this or just do the direct instantiation.
                string connStr = RestSchemaModel.RestSchemaHelper.BuildEFConnectionString(
                    mgrApp.SQLServer, mgrApp.SQLServerDB, mgrApp.SQLServerUser, mgrApp.SQLServerPassword);

                schemaRepo.IApplicationRepository repo2 = new schemaRepo.EFApplicationRepository(connStr);
                schemaModel.Application schApp = repo2.FindBy(mgrApp.ApplicationID, true);

                if (schApp != null)
                {
                    if (nodeParts.Length == 1)
                    {
                        foreach (schemaModel.Domain d in schApp.Domains)
                        {
                            if (d.Parent == null)
                            {
                                if (rslt != "")
                                    rslt += ",";

                                string nodeID = mgrApp.ManagedAppID.ToString() + "-" + d.DomainID;

                                //1. Make each application a non-leaf so that it gets expanded. 
                                //2. Set the cls to the cls sent from the browser
                                rslt += string.Format(@"{{""id"":""{0}"",""leaf"":false,""text"":""{1}"",""qtip"":""{1}"",""cls"":""{2}""}}",
                                    nodeID, d.DomainName, domainNodeCls);
                            }
                        }
                    }
                    //****** PROCESSING CHILDREN OF A DOMAIN NODE *****//
                    else
                    {
                        string domainID = nodeParts[1];

                        schemaModel.Domain domain = repo2.FindDomainBy(domainID, true);

                        foreach (schemaModel.Domain d in domain.Children)
                        {
                            if (rslt != "")
                                rslt += ",";

                            string nodeID = mgrApp.ManagedAppID.ToString()
                                + "-" + d.DomainID;

                            //1. Make each application a non-leaf so that it gets expanded. 
                            //2. Set the cls to the cls sent from the browser
                            rslt += string.Format(@"{{""id"":""{0}"",""leaf"":false,""text"":""{1}"",""qtip"":""{1}"",""cls"":""{2}""}}",
                                nodeID, d.DomainName, domainNodeCls);
                        }
                    }
                }
            }
            ctx.Response.Write("[" + rslt + "]");
            return;
        }
            
        /*Get is for Retrievals*/
        public override void ProcessGet(WADLContext context)
        {

            //HttpContext ctx = HttpContext.Current;

            //if (ctx.Request.Params["getTree"]+"" != "")
            //{
            //    ProcessTreeRequest(context);
            //    return;
            //}

            //if (context.DomainId.HasValue)
            //{
            //    mgrModel.ManagedApp app = repo.FindBy(context.DomainId.Value);
            //    string resp = RestHelper.FormatObjectResponse<mgrModel.ManagedApp>(app, context.ResponseFormat);
            //    ctx.Response.Write(resp);
            //}
            //else
            //{
            //    IList<mgrModel.ManagedApp> records = repo.FindAll(context.Start, context.Limit, context.Sort, context.SortDirection);
            //    int cnt = repo.Count();
            //    ctx.Response.Write(RestHelper.FormatListResponse(records, context.ResponseFormat, cnt));
            //}
        }

        /*Post is for Adds*/
        public override void ProcessPost(WADLContext context)
        {
            //ResponseFormat fmt = ResponseFormat.EXTJS_JSON; //the requested response format.

            //if (!context.DomainId.HasValue)
            //{
            //    string errmsg = RestHelper.FormatErrorResponse("A numeric ApplicationID was not found in either the URL or the posted form.");
            //    HttpContext.Current.Response.Write(errmsg);
            //    return;
            //}
            //HttpContext ctx = HttpContext.Current;
            //mgrModel.ManagedApp rec = (mgrModel.ManagedApp)ProcessorHelper.GetDeserializedObjectFromRequestStream(ctx, typeof(mgrModel.ManagedApp));
            //mgrRepo.IManagedAppRepository repo = RepositoryFactory.GetRepository<mgrRepo.IManagedAppRepository, mgrModel.ManagedApp>();
            //repo.Change(rec);
            //ctx.Response.Write(RestHelper.FormatObjectResponse<mgrModel.ManagedApp>(rec, fmt));
        }
        
        /*Put is for Updates*/
        public override void ProcessPut(WADLContext context)
        {
            ResponseFormat fmt = ResponseFormat.EXTJS_JSON; //the requested response format.
            HttpContext ctx = HttpContext.Current;
            mgrModel.ManagedApp rec = (mgrModel.ManagedApp)ProcessorHelper.GetDeserializedObjectFromRequestStream(ctx, typeof(mgrModel.ManagedApp));

            mgrRepo.IManagedAppRepository repo = RepositoryFactory.GetRepository<mgrRepo.IManagedAppRepository, mgrModel.ManagedApp>();
            repo.Add(rec);
            ctx.Response.Write(RestHelper.FormatObjectResponse<mgrModel.ManagedApp>(rec, fmt));
        }
    }
}